<template>
  <Space direction="vertical" class="imageUploader">
    <Upload
      name="file"
      listType="picture-card"
      class="uploader"
      :max-count="1"
      :show-upload-list="false"
      :disabled="loading.state.value"
      :on-remove="() => onChange?.('')"
      :custom-request="((options:any) => {
        if (options.file) {
          uploadFile(options.file as File)
        }
      })"
    >
      <img v-if="value" class="image" :src="value" :alt="value" />
      <div v-else class="tigger">
        <template v-if="uploader?.uploading.state.value">
          <LoadingOutlined />
        </template>
        <template v-else>
          <PlusOutlined />
        </template>
        <p class="uploadText">
          {{ uploader?.uploading.state.value ? 'UPLOADING...' : 'UPLOAD' }}
        </p>
      </div>
    </Upload>
    <template v-if="!disabledInput">
      <Input
        :allowclear="true"
        placeholder="可以直接输入地址"
        :value="value"
        @change="(event) => onChange?.(event.target.value!)"
      >
        <template #prefix>
          <LinkOutlined />
        </template>
      </Input>
    </template>
    <template v-if="!disabledMarkdown && value">
      <InputGroup :compact="true">
        <Input
          :style="{ width: 'calc(100% - 32px - 1px)' }"
          :readOnly="true"
          placeholder="Markdown image"
          :value="imageURLToMarkdown(value)"
        >
          <template #prefix>
            <FileMarkdownOutlined />
          </template>
        </Input>
        <Tooltip title="Copy Markdown">
          <Button @click="() => copy(imageURLToMarkdown(value!))">
            <template #icon>
              <CopyOutlined />
            </template>
          </Button>
        </Tooltip>
      </InputGroup>
    </template>
  </Space>
</template>

<script lang="ts" setup>
import { PropType } from 'vue'
import {
  LoadingOutlined,
  PlusOutlined,
  FileMarkdownOutlined,
  CopyOutlined,
  LinkOutlined,
} from '@ant-design/icons-vue'
import { copy } from '@/services/clipboard'
import { useLoading } from '@/handcer'
import { Button, Input, InputGroup, Space, Tooltip, Upload, notification } from 'ant-design-vue'
import { useUploader, UploadErrorCode } from '@/services/uploader'
import { imageURLToMarkdown } from '@/transformers/markdown'

const getFileName = (file: File, directory?: string) => {
  const _directory = directory ? `${directory}/` : ''
  return `${_directory}${file.name.replace(/ /gi, '')}`
}

const props = defineProps({
  value: {
    type: String,
  },
  onChange: {
    type: Function as PropType<(value: string) => void>,
  },
  directory: {
    type: String,
  },
  disabledInput: {
    type: Boolean,
  },
  disabledMarkdown: {
    type: Boolean,
  },
})

const loading = useLoading()
const uploader = useUploader()

const uploadFile = (file: File) => {
  notification.info({
    message: '开始上传',
    description: '文件开始上传',
  })

  uploader
    .upload(file, getFileName(file, props.directory))
    .then((result) => {
      props.onChange?.(result.url)
      notification.success({
        message: '上传成功',
        description: result.key,
      })
    })
    .catch((error) => {
      notification.error({
        message: '上传失败',
        description:
          error.code === UploadErrorCode.Failure
            ? String(error.error?.message ?? error.error)
            : error.code,
      })
    })
}
</script>

<style lang="less" scoped>
.multipleImageUploader {
  width: 100%;

  .copyButton {
    margin-bottom: 1rem;
  }

  :global(.ant-upload-list-item) {
    margin-top: 1rem !important;
  }
}

.imageUploader {
  width: 100%;

  .uploader {
    :global(.ant-upload.ant-upload-select-picture-card) {
      width: 100%;
      height: auto;
      margin: 0;
    }

    .image {
      width: 100%;
      min-height: 100px;
    }

    .tigger {
      width: 100%;
      padding: 2rem 0;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }

    .uploadText {
      margin-top: 8px;
    }
  }
}
</style>
